﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Net.Sockets;
using System.Threading;
using System.Net;
using System.Text.RegularExpressions;
using System.Globalization;
using System.Windows.Forms;
using System.Data;

namespace WindowsForms01
{
    public  class CsToPcSoket
    {
        #region 客户端发送至PC服务器
        //使用IPv4地址，流式socket方式，tcp协议传递数据
        Socket Cenlitsoketsend =null/* new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)*/;
        public string recstr;
        int count = 0;
        int reclen;
        TimeSpan timeSpanstart = new TimeSpan(DateTime.Now.Ticks);
        //bool Isconnetion = false;
        /// <summary>
        /// 发送命令
        /// </summary>
        /// <param name="str">命令字符串</param>
        /// <returns></returns>
        public  string Gocmd(string str)//命令执行
        {
            try
            {
                //byte[] buffer = Encoding.UTF8.GetBytes(str + Environment.NewLine);
                bool b_v = SoketConnetion(CSReadPlc.ToPcIP, CSReadPlc.ToPcIPoint);
                if (b_v)
                {
                    byte[] buffer = Encoding.UTF8.GetBytes(str);
                    recstr = "";
                    //if (Cenlitsoketsend.Connected)
                    //{
                        Cenlitsoketsend.Send(buffer);
                    //}
                    TimeSpan timeSpanstart = new TimeSpan(DateTime.Now.Ticks);
                    while (recstr.Trim() != "OK")
                    {
                        TimeSpan timeSpanstop = new TimeSpan(DateTime.Now.Ticks);
                        TimeSpan ts = timeSpanstart.Subtract(timeSpanstop).Duration();
                        if (ts.Seconds > 500)
                        {
                            count++;
                            if (count < 2)//第一次发送失败后执行第二次发送
                                recstr = Gocmd(str);
                            recstr = "超时";
                            break;
                        }
                    }
                    //释放本次连接
                    //Cenlitsoketsend.Shutdown(SocketShutdown.Both);
                    //Cenlitsoketsend.Disconnect(true);
                    //Cenlitsoketsend.Close();
                }
                else
                {
                    MessageBox.Show("PC服务器连接已断开");
                    Cslogfun.WriteToLog("PC服务器连接已断开");
                }
            }
            catch (Exception err)
            {
                Cslogfun.WriteToLog(err);
                throw new Exception("提示：" + err.Message);
            }
            return recstr;
        }
        public bool SoketConnetion(string ServerIP, string ServerPoint) //建立soket连接
        {
            //重新创建一个Soket对象，这一步必须的
            Cenlitsoketsend = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            bool Isconnetion = false;
            //连接到的目标IP
            IPAddress ip_ = IPAddress.Parse(ServerIP);
            //连接到目标IP的哪个应用(端口号！)
            IPEndPoint point_ = new IPEndPoint(ip_, int.Parse(ServerPoint));
            try
            {
                //连接到服务器,已经连接无需再连
                if (!Cenlitsoketsend.Connected)
                {
                    Cenlitsoketsend.Connect(point_);
                    //Cenlitsoketsend.BeginConnect(point_, null, null);
                    Thread th = new Thread(ReceiveMsg);
                    th.IsBackground = true;
                    th.Start();
                }
                if (Cenlitsoketsend.Connected)
                {
                    Isconnetion = true;
                }
            }
            catch (Exception err)
            {
                Cslogfun.WriteToLog(err);
                MessageBox.Show("提示：PC服务器连接失败，" + err.ToString());
            }
            return Isconnetion;
        }
        void ReceiveMsg()//接受服务器端返回数据信息
        {
            string strre = "";
            while (true)
            {
                Thread.Sleep(100);
                try
                {
                    if (Cenlitsoketsend.Connected)
                    {
                        reclen = 0;
                        byte[] buffer = new byte[1024];
                        if (Cenlitsoketsend.Connected)
                            reclen = Cenlitsoketsend.Receive(buffer, buffer.Length, 0);
                        else
                        {
                            Cslogfun.WriteToLog("PC服务器连接已断开");
                            MessageBox.Show("PC服务器连接已断开");
                        }
                        strre = Encoding.UTF8.GetString(buffer, 0, reclen);
                        if (reclen > 0 && strre.Contains("OK") == true)
                        {
                            recstr = "OK";
                            Cslogfun.WriteToPCsoketLog("服务器接受成功并反馈OK信号");
                        }
                        strre = "";
                    }
                }
                catch (Exception err)
                {
                    Cslogfun.WriteToLog(err);
                    MessageBox.Show("提示：" + err.ToString());
                    bool b_v = SoketConnetion(CSReadPlc.ToPcIP, CSReadPlc.ToPcIPoint);
                    if (!b_v)
                    {
                        MessageBox.Show("1号线上位机未连接上,请确认再将2号线上位机软件启动");
                        System.Environment.Exit(0);
                    }
                }
            }
        }
        #endregion
        #region 服务器端
        public void ListenStart(string PcserverIPoint)
        {
            try
            {
                //点击开始监听时 在服务端创建一个负责监听IP和端口号的Socket
                System.Net.Sockets.Socket socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                IPAddress ip = IPAddress.Any;
                //创建对象端口
                IPEndPoint point = new IPEndPoint(ip, Convert.ToInt32(PcserverIPoint.Trim()));
                socketWatch.Bind(point);//绑定端口号
                Cslogfun.WriteToPCsoketLog("监听成功!");
                socketWatch.Listen(10);//设置监听
                //创建监听线程
                Thread thread = new Thread(Listen);
                thread.IsBackground = true;
                thread.Start(socketWatch);
            }
            catch(Exception err)
            {
                Cslogfun.WriteToLog(err);
                throw new Exception("提示：" + err.Message);
            }
        }
        Socket ServerSoketSend;
        void Listen(object o)
        {
            try
            {
                Socket socketWatch = o as Socket;
                while (true)
                {
                    ServerSoketSend = socketWatch.Accept();//等待接收客户端连接
                    Cslogfun.WriteToPCsoketLog(ServerSoketSend.RemoteEndPoint.ToString() + ":" + "连接成功!");
                    //开启一个新线程，执行接收消息方法
                    Thread r_thread = new Thread(Received);
                    r_thread.IsBackground = true;
                    r_thread.Start(ServerSoketSend);
                }
            }
            catch(Exception err)
            {
                Cslogfun.WriteToLog(err);
                MessageBox.Show(err.ToString());
            }
        }
        /// <summary>
        /// 服务器端不停的接收客户端发来的消息
        /// </summary>
        /// <param name="o"></param>
        void Received(object o)
        {
            try
            {
                Socket socketSend = o as Socket;
                while (true)
                {
                    Thread.Sleep(100);
                    if (socketSend.Connected)
                    {
                        //客户端连接服务器成功后，服务器接收客户端发送的消息
                        byte[] buffer = new byte[1024];
                        //实际接收到的有效字节数
                        int len = socketSend.Receive(buffer);
                        if (len == 0)
                        {
                            continue;
                        }
                        string str = Encoding.UTF8.GetString(buffer, 0, len);
                        if (str.Contains("<"))
                        {
                            CSReadPlc.ToPcStr = CsGetData.GetCenlitData(str);
                            Cslogfun.WriteToPCsoketLog(socketSend.RemoteEndPoint + ":" + str);
                            Send("OK");
                        }
                    }
                }
            }
            catch (Exception err)
            {
                Cslogfun.WriteToLog(err);
                MessageBox.Show("提示：" + err.ToString());
            }
        }
        /// <summary>
        /// 服务器向客户端发送消息
        /// </summary>
        /// <param name="str"></param>
        public void Send(string str)
        {
            try
            {
                if (ServerSoketSend.Connected)
                {
                    byte[] buffer = Encoding.UTF8.GetBytes(str);
                    ServerSoketSend.Send(buffer);
                }
            }
            catch (Exception err)
            {
                Cslogfun.WriteToLog(err);
                throw new Exception("提示：" + err.Message);
            }
        }
        #endregion
    }
}
